﻿using MovingChame.Web.Helpers;
using MovingChame.Web.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace MovingChame.Web.Infrastructure
{
    public class AbstractTourProvider : IAbstractTourProvider
    {
        private static AbstractTourProvider current;
        public static AbstractTourProvider Current
        {
            get
            {
                if (current == null) current = new AbstractTourProvider();
                return current;
            }
        }

        #region Configuration
        private string applicationName;
        public string ApplicationName
        {
            get { return applicationName; }
            set { applicationName = value; }
        }

        private string connectionStringName;
        private string providerName;
        private MovingChameModelContainer db;

        public void Initialize(string name, System.Collections.Specialized.NameValueCollection config)
        {
            providerName = name;

            if (config["applicationName"] != null)
                applicationName = config["applicationName"];

            if (config["connectionStringName"] != null)
            {
                connectionStringName = config["connectionStringName"];
                db = new MovingChameModelContainer();
                db.Database.Connection.ConnectionString = ConfigurationHelper.GetConnectionString(connectionStringName);
            }
            else
                db = new MovingChameModelContainer();
        }

        private AbstractTourProvider()
        {
            Initialize("AbstractTourProvider", new System.Collections.Specialized.NameValueCollection());
        }
        #endregion

        #region Interfact Methods
        public int AddAbstractTour(string name, int tourLength, TourType tourType, ViewProperty viewProperty, string startLocation,
            string summary, string description)
        {
            var abstractTour = new AbstractTour
            {
                Name = name,
                TourLength = tourLength,
                Type = tourType,
                ViewProperty = viewProperty,
                StartLocation = startLocation,
                Summary = summary,
                Description = description
            };

            db.AbstractTours.Add(abstractTour);
            db.SaveChanges();

            return abstractTour.Id;
        }

        public bool UpdatePlanningAbstractTour(int abstractTourId, AbstractTour updatedAbstractTour)
        {
            AbstractTour tour = GetAbstractTourById(abstractTourId);
            if (tour == null)
                return false;
            if (tour.ViewProperty != ViewProperty.Planning)
                return false;
            db.Entry(tour).CurrentValues.SetValues(updatedAbstractTour);
            db.SaveChanges();
            return true;
        }

        public bool ActivateAbstractTour(int abstractTourId)
        {
            var updatedTour = db.AbstractTours.SingleOrDefault(o => o.Id == abstractTourId);
            if (updatedTour.User.Roles.SingleOrDefault(o=>o.Name=="company") != null)
                updatedTour.ViewProperty = ViewProperty.Official;
            else
                updatedTour.ViewProperty = ViewProperty.Unofficial;
            db.SaveChanges();
            return true;
        }

        public bool RemoveAbstractTour(int abstractTourId)
        {
            var updatedTour = db.AbstractTours.SingleOrDefault(o => o.Id == abstractTourId);
            if (updatedTour.ViewProperty == ViewProperty.Deactive)
            {
                return false;
            }
            updatedTour.ViewProperty = ViewProperty.Deactive;
            db.SaveChanges();
            return true;
        }

        public AbstractTour GetAbstractTourById(int abstractTourId)
        {
            return db.AbstractTours.SingleOrDefault(o => o.Id == abstractTourId);
        }

        public IQueryable<AbstractTour> SearchAbstractToursInName(string keyword)
        {
            return db.AbstractTours.Where(o => o.Name.Contains(keyword));
        }

        public IQueryable<AbstractTour> GetAbstractToursByCreator(int creatorId)
        {
            return db.AbstractTours.Where(o => o.User_Id == creatorId);
        }

        public IQueryable<AbstractTour> GetOfficialAbstractTours()
        {
            return db.AbstractTours.Where(o => o.ViewProperty == ViewProperty.Official);
        }

        public IQueryable<AbstractTour> GetUnofficialAbstractTours()
        {
            return db.AbstractTours.Where(o => o.ViewProperty == ViewProperty.Unofficial);
        }

        public IQueryable<AbstractTour> GetAbstractToursByStartLocation(string startLocationName)
        {
            return db.AbstractTours.Where(o => o.StartLocation.Contains(startLocationName));
        }

        public IQueryable<AbstractTour> GetPrivateTours(int userId) 
        {
            return db.AbstractTours.Where(o => o.User_Id == userId).Where(o => o.ViewProperty == ViewProperty.Private);
        }
        #endregion
    }
}